function fm_axesdlg(varargin)
%SCRIBEAXESDLG   Axes property dialog helper function for Plot Editor
%   SCRIBEAXESDLG(A)  opens axes property dialog for axes A
%
%   If the plot editor is active, the SCRIBEAXESDLG edits all
%   currently selected axes.  Alternatively, SCRIBEAXESDLG(S)
%   explicitly passes a selection list S, a row vector
%   of scribehandle objects, to SCRIBEAXESDLG for editing.
%
%   Copyright 1984-2001 The MathWorks, Inc.
%   $Revision: 1.27 $  $Date: 2001/04/15 12:01:20 $
%   j. H. Roh
%
%Modified by:    Federico Milano
%Date:      11-Nov-2002
%Version:   1.0.0
%
%E-mail:    Federico.Milano@uclm.es
%Web-site:  http://www.uclm.es/area/gsee/Web/Federico

persistent localData;

switch nargin
case 1
    arg1 = varargin{1};

    if isempty(arg1) || ishandle(arg1) || isa(arg1(1),'scribehandle')
        localData = LInitFig(arg1,localData);
        return
    elseif ischar(arg1)
        action = arg1;
        parameter = [];
    end

case 2
    action = varargin{1};
    parameter = varargin{2};

end

if strcmp(parameter,'me')
    parameter = gcbo;
end


localData = feval(action,parameter,localData);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function localData = showhelp(selection, localData)
try
    helpview([docroot '/mapfiles/plotedit.map'], ...
        'pe_ax_props', 'PlotEditPlain');
catch
    errordlg(['Unable to display help for Axes Properties:' ...
            sprintf('\n') lasterr ]);
end

function localData = button(selection, localData);
switch selection
case 'cancel'
    close(gcbf);
case 'ok'
    set(gcbf,'Pointer','watch');
    localData = LApplySettings(gcbf,localData);
    close(gcbf);
case 'apply'
    set(gcbf,'Pointer','watch');
    localData = LApplySettings(gcbf,localData);
    set(gcbf,'Pointer','arrow');
end

function localData = verifynumber(uic, localData)
iGroup = find(uic==localData.LimCheck);
val = str2double(get(uic,'String'));
if ~isnan(val)
    if length(val)==1
        localData.OldVal{iGroup} = val;
        return
    end
end
% trap errors
set(uic,'String',num2str(localData.OldVal{iGroup}));
fieldName = get(uic,'ToolTip');
errordlg([fieldName ' field requires a single numeric input'],'Error','modal');





function localData = key(fig,localData);
theKey = get(fig,'CurrentCharacter');
if isempty(theKey), return, end

switch theKey
case 13 % return
    fm_axesdlg button ok;
case 27 % escape
    fm_axesdlg button cancel;
case 9 % tab
    % next field
end
% manage state of controls


function localData = toggle(uic,localData);

iGroup = find(uic==localData.LimCheck);
Sibling = get(uic,'UserData');

enable = {'off' 'on'};
if isempty(Sibling),
    % Perform as before
    value = get(uic,'Value');
    if ~isempty(iGroup),
        set(localData.LimGroup{iGroup},'Enable',enable{value+1});
    end
else
    % See if the extra checkbox was pressed
    if isempty(get(uic,'String')),
        Sibling=uic; % Reset the Sibling as the current UIcontrol
    end
    SibUd = get(Sibling,'UserData');
    % Toggle the extra check box state
    if strcmp(get(Sibling,'enable'),'off');
        set(Sibling,'enable','inactive');
        value = get(Sibling,'Value');
    elseif isequal(SibUd.Value,get(Sibling,'Value')),
        set(Sibling,'value',~get(Sibling,'Value'))
        value = get(Sibling,'Value');
    else
        set(Sibling,'enable','off','Value',SibUd.Value);
        value = 0;
    end
    if ~isempty(iGroup),
        set(localData.LimGroup{iGroup},'Enable',enable{value+1});
    end
end % if/else isempty(Sibling)


function localData = radio(uic,localData);
iGroup = find(uic==localData.LimCheck);

Sibling = get(uic,'UserData');

enableflag = 1;
if isempty(Sibling),
    % Perform as before
    set(uic,'Value',1);
    set(localData.LimGroup{iGroup},'Value',0);
else
    if ~isempty(get(uic,'String')),
        iGroup = iGroup+2;
        ActiveButton = localData.LimCheck(iGroup);
        value = ~get(ActiveButton,'Value');
    else
        ActiveButton = uic;
        value = get(ActiveButton,'Value');
    end
    udAB = get(ActiveButton,'UserData');
    udLimGroup = get(localData.LimGroup{iGroup},'UserData');
    udLimGroup.Value = 0;

    % Toggle the active radio button's state
    if strcmp(get(ActiveButton,'enable'),'off');
        udAB.Value = 1;
        set(ActiveButton,'enable','on','Value',1,'UserData',udAB);
        set(localData.LimGroup{iGroup},'Enable','on');
    elseif udAB.Value,
        udAB.Value = 0;
        set(ActiveButton,'Value',0, ...
            'Enable','off','UserData',udAB)
        set(localData.LimGroup{iGroup},'Value',0, ...
            'Enable','off','UserData',udLimGroup)

        % Store the checkbox state,
        if ~isempty(localData.Enable{iGroup}),
            localData.Disable{iGroup-1}.CheckValue = get(localData.Enable{iGroup}(1),'Value');
        end
        enableflag = 0;
    else
        udAB.Value = 1;
        set(ActiveButton,'Value',1,'UserData',udAB);
        set(localData.LimGroup{iGroup},'Value',0,'UserData',udLimGroup)
    end % if/else strcmp(Sibling,'enable'...)
end % if/else length(localData.axes...

% for the linear/log switches
disableGroup = localData.Disable{iGroup};
if ~isempty(disableGroup) && enableflag,
    if any(strcmp(get(disableGroup.Controls,'Enable'),'on')) ,
        set(disableGroup.Controls,'Enable','off');
        % Save the checkbox value
        localData.Disable{iGroup}.CheckValue = get(disableGroup.Controls(1),'Value');
    end
    set(disableGroup.Controls(1),'Value',0);           % uncheck
    Sibling = get(disableGroup.Controls(1),'UserData');
    if ~isempty(Sibling),
        set(Sibling,'Value',0,'Enable','off','HitTest','off');
    end
end
enableGroup = localData.Enable{iGroup};
if ~isempty(enableGroup) && enableflag,
    Sibling = get(enableGroup(1),'UserData');
    if ~isempty(Sibling),
        value = get(Sibling,'Value');
    else
        value = get(enableGroup(1),'Value');
    end
    if ~value
        set(enableGroup(1),'Enable','on',...
            'Value',localData.Disable{iGroup-1}.CheckValue);     % enable checkbox
    else
        set(enableGroup,'Enable','on');  % enable both
        set(enableGroup(1),'Value',localData.Disable{iGroup-1}.CheckValue);
    end % if/else value
    if ~isempty(Sibling),
        set(Sibling,'HitTest','on','Value',localData.Disable{iGroup-1}.CheckValue);
    end
else
    set(enableGroup,'Enable','off'); % disable both
end


function localData = LInitFig(ax,localData)

if isempty(ax)
    LNoAxesError;
    return
end

try
    if ishandle(ax)
        fig = get(ax(1),'Parent');
    else
        % might be any selected object
        fig = get(ax(1),'Figure');
    end
catch
    errordlg(['Unable to edit axes properties: invalid axes' ...
            ' handles.']);
    return
end

oldPointer = get(fig,'Pointer');
set(fig,'Pointer','watch');

try
    % look for a list of selected objects
    HG = [];
    if ~plotedit(fig,'isactive')
        % plotedit has not been activated and we have a list of HG handles
        HG = ax;     % take the original handle list

    else
        % call from the Figure Tools menu or from context menu
        % ax is a selection list
        for aObj = ax
            aHG = get(aObj,'MyHGHandle');
            if strcmp('axes',get(aHG,'Type'))
                HG(end+1) = aHG;
            end
        end
    end
catch
    set(fig,'Pointer',oldPointer);
    errordlg(['Unable to open Axes Properties dialog. ' ...
            'Selection list is invalid:' ...
            10 lasterr]);
    return
end

if isempty(HG)
    LNoAxesError;
    set(fig,'Pointer',oldPointer);
    return
end

%--temporary:  redirect to Property Editor
%propedit(HG);
%set(fig,'Pointer',oldPointer);
%return

ax = HG;

try
    % Property constants
    White = [1 1 1];
    Black = [0 0 0];

    % Check each axes, if one is 3D
    allViews = get(ax,{'view'});
    f2D = isequal(allViews{:},[0 90]);

    bgcolor = get(0,'DefaultUIControlBackgroundColor');
    if bgcolor==Black
        fgcolor = White;
    else
        fgcolor = get(0,'DefaultUIControlForegroundColor');
    end

    % adjustment factors for character units
    % work in character units.
    fx = 5;
    fy = 13;

    fProps = struct(...
        'Units', get(fig,'Units'),...
        'NumberTitle', 'off',...
        'IntegerHandle', 'off',...
        'Pointer','watch', ...
        'Resize', 'on',...
        'Color', bgcolor,...
        'Visible', 'off',...
        'KeyPressFcn', 'fm_axesdlg key me',...
        'WindowStyle', 'modal',...
        'Name', 'Edit Axes Properties', ...
        'Position', get(fig,'Position'));
    f = figure(fProps);
    set(f,'Units','character');
    figPos = get(f,'Position');

    figWidth = 550/fx;
    figHeight = 325/fy;

    % center dialog over the calling window
    figPos(1:2) = figPos(1:2) + (figPos(3:4)-[figWidth, figHeight])/2;
    figPos(3:4) = [figWidth, figHeight];
    set(f,'Position',figPos);

    enable = {'off' 'on'};

    % geometry
    LMarginW = 15/fx;
    RMarginW = 25/fx;
    ColPadW = 20/fx;
    RowPadH = 9/fy;

    RowLabelW = 70/fx;
    if f2D
        nCols = 2;
    else
        nCols = 3;
    end
    data.nCols = nCols;
    setappdata(f,'ScribeAxesDialogData',data);

    ColW = (figPos(3)-RowLabelW-LMarginW-RMarginW-nCols*ColPadW)/nCols;

    TopMarginH = 20/fy;
    BotMarginH = 20/fy;
    TitleH = 25/fy;
    HeaderH = 30/fy;
    RowH = 30/fy;

    buttonW = 72/fx;
    buttonH = RowH-RowPadH;
    buttonPad = 7/fx;

    XCol(1) = LMarginW;
    XCol(2) = XCol(1) + RowLabelW + ColPadW;
    XCol(3) = XCol(2) + ColW + ColPadW;
    XCol(4) = XCol(3) + ColW + ColPadW;


    % defaults for each style
    editProps = struct(...
        'Parent', f,...
        'Style', 'edit',...
        'Units', 'character',...
        'BackgroundColor', White,...
        'ForegroundColor', Black,...
        'HorizontalAlignment', 'left',...
        'Callback', 'fm_axesdlg verifynumber me');

    checkProps = struct(...
        'Parent', f,...
        'Style', 'checkbox',...
        'Units', 'character',...
        'HorizontalAlignment', 'left',...
        'BackgroundColor', bgcolor,...
        'ForegroundColor', fgcolor,...
        'Callback', 'fm_axesdlg toggle me');

    radioProps = struct(...
        'Parent', f,...
        'Style', 'radio',...
        'Units', 'character',...
        'HorizontalAlignment', 'left',...
        'BackgroundColor', bgcolor,...
        'ForegroundColor', fgcolor,...
        'Callback', 'fm_axesdlg radio me');

    tProps = struct(...
        'Parent', f,...
        'Style', 'text',...
        'Units', 'character',...
        'HorizontalAlignment', 'right',...
        'BackgroundColor', bgcolor,...
        'ForegroundColor', fgcolor);

    % get text size
    ut = uicontrol(tProps,...
        'Visible','off',...
        'String','Title');
    charSize = get(ut,'Extent');
    charH = charSize(4);
    delete(ut);

    % charOffset = (RowH-charH)/2;
    editH = charH + 4/fy;
    uiH = RowH-RowPadH;

    YTitleRow = figPos(4)-TitleH-TopMarginH-uiH;

    % Title row
    charOffset = uiH-charH;
    uicontrol(tProps,...
        'FontWeight','bold',...
        'String', 'Title:',...
        'Position', ...
        [ LMarginW  YTitleRow + uiH + uiH - charH ...
            RowLabelW charH]);

        % Check for similar titles
        titleHandle = get(ax,{'Title'});
        titleString = get([titleHandle{:}],{'String'});
        if isempty(titleString{1}) || ...
                (length(titleString) > 1 && ~isequal(titleString{:})),
            % use a cell array, so spaces aren't padded out.
            CommonFlag = 0;
            titleString = {};
        else
            CommonFlag  = 1;
            titleString=titleString{1};
        end
        titleU = uicontrol(editProps,...
            'Tag', 'Title',...
            'UserData',CommonFlag, ...
            'Callback', '',...
            'HorizontalAlignment','center',...
            'Max', 2, ... % allow multi line titles
            'String', titleString,...
            'Position', ...
            [ XCol(2)           YTitleRow ...
                nCols*ColW+(nCols-1)*ColPadW  uiH + uiH]);

        iGroup=1;
        localData.LimCheck(iGroup)=titleU;
        localData.Prop{iGroup} = 'Title';

        % put down the row headings

        rowLabelStrings = {...
                '','left',
            'Label:','right',
            'Limits:','right',
            'Tick Step:','right',
            'Scale:','right',
            '','right',
            'Grid:','right',
            '','right',
        };
        nRows = size(rowLabelStrings,1);
        Y = YTitleRow - HeaderH + RowPadH;
        headingPosition = [LMarginW Y RowLabelW charH];

        for iRow = 1:nRows,
            if ~isempty(rowLabelStrings{iRow,1})
                headingPosition(2) = Y;
                uicontrol(tProps,...
                    'FontWeight', 'bold',...
                    'String', rowLabelStrings{iRow,1},...
                    'HorizontalAlignment', rowLabelStrings{iRow,2},...
                    'Position', headingPosition);
            end
            Y = Y-RowH;
        end

        % fill each column

        cCol = ' XYZ';
        for iCol = 2:nCols+1,

            X = XCol(iCol);
            col = cCol(iCol);

            % heading
            Y = YTitleRow - HeaderH + RowPadH;
            uicontrol(tProps,...
                'Style', 'text',...
                'FontWeight', 'bold',...
                'HorizontalAlignment', 'center',...
                'Position', [X Y-charOffset ColW charH],...
                'String', col);

            % label
            Y = Y-RowH;

            % Check for similar labels
            labelHandle = get(ax,{[col 'Label']});
            labelString = get([labelHandle{:}],{'String'});
            if isempty(labelString{1}) || ...
                    (length(labelString)>1 && ~isequal(labelString{:})),
                % use a cell array, so spaces aren't padded out.
                CommonFlag = 0;
                labelString = {};
            else
                labelString=labelString{1};
                CommonFlag = 1;
            end
            if size(labelString,1)>1  % multiline label
                multiline = 2;
            else
                multiline = 1;
            end
            labelU = uicontrol(editProps,...
                'Enable', 'on',...
                'Tag', [col 'Label'],...
                'ToolTip', [col 'Label'],...
                'UserData',CommonFlag, ...
                'Position', [X Y ColW uiH ],...
                'String', labelString,...
                'Max', multiline,...
                'Callback', '');

            iGroup = iGroup+1;
            localData.LimCheck(iGroup) = labelU;
            localData.Prop{iGroup} = 'Title';

            % range
            Y = Y-RowH;

            % Check if all axes are manual or auto
            AllMods = strcmp(get(ax, [col 'LimMode']),'manual');
            MultMods = 0;
            if all(~AllMods)
                checkProps.Value = 0;
            elseif all(AllMods)
                checkProps.Value = 1;
            else
                MultMods = 1;
                checkProps.Value = length(find(AllMods))>=length(find(~AllMods));
            end

            CheckVal = checkProps.Value;
            clim = uicontrol(checkProps,...
                'String', 'Manual',...
                'Tag', [col 'LimMode'],...
                'ToolTip', [col 'LimMode'],...
                'Position', [X Y ColW/2 uiH]);

            % Add a second checkbox when editing multiple axes
            if MultMods,
                % Overwrite the other checkbox, since it's callback will never
                % be invoked
                clim2 = uicontrol(checkProps,...
                    'ButtonDownFcn','fm_axesdlg toggle me', ...
                    'Enable','off', ...
                    'Tag', [col 'LimMode'],...
                    'ToolTip', [col 'LimMode'],...
                    'UserData',struct('Value',checkProps.Value,'Sibling',clim), ...
                    'Position', [X Y 3 uiH]);
                checkProps.Value = 0;
                set(clim,'UserData',clim2,'Tag','')
            end

            % Check for common limits
            lim = get(ax,{[col 'Lim']});
            lim = cat(1,lim{:});
            Umin = unique(lim(:,1));
            Umax = unique(lim(:,2));
            if length(Umin)>1, uminStr = '';
            else, uminStr = num2str(Umin);
            end
            if length(Umax)>1, umaxStr = '';
            else, umaxStr = num2str(Umax);
            end

            umin = uicontrol(editProps,...
                'Tag', [col 'LimMin'],...
                'ToolTip', [col ' Min'],...
                'Enable', enable{checkProps.Value+1},...
                'String', uminStr,...
                'Position', [X+ColW/2 Y ColW/4 uiH]);

            iGroup=iGroup+1;
            localData.LimCheck(iGroup) = umin;
            localData.OldVal{iGroup} = min(lim);

            umax = uicontrol(editProps,...
                'Tag', [col 'LimMax'],...
                'Enable', enable{checkProps.Value+1},...
                'String', umaxStr,...
                'Position', [X+ColW*3/4 Y ColW/4 uiH],...
                'ToolTip', [col ' Max']);
            iGroup = iGroup+1;
            localData.LimCheck(iGroup) = umax;
            localData.OldVal{iGroup} = max(lim);

            iGroup = iGroup+1;
            localData.LimGroup{iGroup} = [umin umax];
            localData.LimCheck(iGroup) = clim;
            localData.Prop{iGroup} = [col 'LimMode'];

            if MultMods
                iGroup = iGroup+1;
                localData.LimGroup{iGroup} = [umin umax];
                localData.LimCheck(iGroup) = clim2;
                localData.Prop{iGroup} = [col 'LimMode'];
            end

            % Check if all axes use a linear scale
            AllScales = strcmp(get(ax,[col 'Scale']),'linear');
            MultScales = 0;
            if all(~AllScales)
                linearScale = 0;
            elseif all(AllScales)
                linearScale = 1;
            else
                MultScales = 1;
                linearScale=0;
            end

            % tickstep
            Y = Y-RowH;

            % Check if all TickModes are manual or auto
            AllMods = strcmp(get(ax, [col 'TickMode']),'manual');
            MultMods = 0;
            if all(~AllMods)
                checkProps.Value = 0;
            elseif all(AllMods)
                checkProps.Value = 1;
            else
                MultMods = 1;
                checkProps.Value = length(find(AllMods))>=length(find(~AllMods));
            end

            CheckVal = checkProps.Value;
            clim = uicontrol(checkProps,...
                'String', 'Manual',...
                'Tag', [col 'TickMode'],...
                'Enable', enable{linearScale+1},...
                'ToolTip', [col 'TickMode'],...
                'Position', [X Y ColW/2 uiH]);

            % Add a second checkbox when editing multiple axes
            if MultMods,
                % Overwrite the other checkbox, since it's callback will never
                % be invoked
                clim2 = uicontrol(checkProps,...
                    'ButtonDownFcn','fm_axesdlg toggle me', ...
                    'Enable','off', ...
                    'Tag', [col 'TickMode'],...
                    'ToolTip', [col 'TickMode'],...
                    'UserData',struct('Value',checkProps.Value,'Sibling',clim), ...
                    'Position', [X Y 3 uiH]);
                checkProps.Value = 0;
                set(clim,'UserData',clim2,'Tag','')
            end

            if linearScale
                editProps.Enable = enable{checkProps.Value+1};
                % Check for common tick marks
                tick = get(ax,{[col 'Tick']});
                if (length(tick)>1 && ~isequal(tick{:})) || isempty(tick{1}) || length(tick{1})<2
                    tickstep = [];
                else
                    tickstep = tick{1}(2)-tick{1}(1);
                end
            else
                editProps.Enable = enable{0+1};
                tickstep = [];
            end
            utick = uicontrol(editProps,...
                'Tag', [col 'TickStep'],...
                'ToolTip', [col ' Tick step size'],...
                'HorizontalAlignment','center',...
                'String', num2str(min(tickstep)),...
                'Position', [X+ColW/2 Y ColW/2 uiH]);
            iGroup = iGroup+1;
            localData.LimCheck(iGroup) = utick;
            localData.OldVal{iGroup} = tickstep;

            iGroup = iGroup+1;
            localData.LimGroup{iGroup} = utick;
            localData.LimCheck(iGroup) = clim;

            if MultMods,
                iGroup = iGroup+1;
                localData.LimGroup{iGroup} = utick;
                localData.LimCheck(iGroup) = clim2;
            end

            % Scale
            Y = Y-RowH;
            radioProps.Value = linearScale;
            rlin = uicontrol(radioProps,...
                'Position', [X Y ColW/2 uiH],...
                'String', 'Linear',...
                'Tag', [col 'ScaleLinear'],...
                'ToolTip',[col 'Scale=''linear''']);

            % Add a second set of radio buttons when editing multiple axes
            if MultScales,
                rlin2 = uicontrol(radioProps,...
                    'ButtonDownFcn','fm_axesdlg radio me', ...
                    'Enable','off', ...
                    'Position', [X Y 3 uiH],...
                    'String', '',...
                    'Tag', [col 'ScaleLinear'],...
                    'ToolTip',[col 'Scale=''linear'''], ...
                    'Value',0);
                set(rlin,'UserData',rlin2,'Tag','');
            end

            Y = Y-RowH*2/3;
            rlog = uicontrol(radioProps,...
                'Position', [X Y ColW/2 uiH],...
                'String', 'Log',...
                'Value', ~radioProps.Value,...
                'Tag', [col 'ScaleLog'],...
                'ToolTip',[col 'Scale=''log''']);

            % Add a second set of radio buttons when editing multiple axes
            if MultScales,
                rlog2 = uicontrol(radioProps,...
                    'Enable','off', ...
                    'Position', [X Y 3 uiH],...
                    'String', '',...
                    'Value', ~radioProps.Value,...
                    'Tag', [col 'ScaleLog'],...
                    'ToolTip',[col 'Scale=''log'''], ...
                    'Value',0);
                set(rlog,'UserData',rlog2,'Tag','');
                set(rlin2,'UserData',...
                    struct('Value',0,'Sibling',rlin,'OtherRadio',rlog2));
                set(rlog2,'UserData',...
                    struct('Value',0,'Sibling',rlog,'OtherRadio',rlin2));
            end
            Y = Y-RowH*1/3;

            iGroup = iGroup+1;
            localData.LimGroup{iGroup} = [rlin];
            localData.LimCheck(iGroup) = rlog;
            localData.Enable{iGroup} = [];
            localData.Disable{iGroup} = struct('Controls',[clim utick], ...
                'CheckValue',CheckVal);

            iGroup = iGroup+1;
            localData.LimGroup{iGroup} = [rlog];
            localData.LimCheck(iGroup) = rlin;
            localData.Enable{iGroup} = [clim utick];  % checkbox then
            % other control
            localData.Disable{iGroup} = [];

            if MultScales
                iGroup = iGroup+1;
                localData.LimGroup{iGroup} = [rlin2];
                localData.LimCheck(iGroup) = rlog2;
                localData.Enable{iGroup} = [];
                localData.Disable{iGroup} = struct('Controls',[clim utick], ...
                    'CheckValue',CheckVal);

                iGroup = iGroup+1;
                localData.LimGroup{iGroup} = [rlog2];
                localData.LimCheck(iGroup) = rlin2;
                localData.Enable{iGroup} = [clim utick];  % checkbox then
                % other control
                localData.Disable{iGroup} = [];
            end

            % Direction
            Y = Y+RowH;

            % Check if all axes use a normal dirction
            AllDirs = strcmp(get(ax, [col 'Dir']),'normal');
            MultDirs = 0;
            if all(~AllDirs)
                radioProps.Value = 0;
            elseif all(AllDirs)
                radioProps.Value = 1;
            else
                MultDirs= 1;
                radioProps.Value = 0;
            end

            rnormal = uicontrol(radioProps,...
                'Position', [X+ColW/2 Y ColW/2 uiH],...
                'String', 'Normal',...
                'Tag', [col 'DirNormal'],...
                'ToolTip',[col 'Dir=''normal''']);

            if MultDirs
                rnormal2 = uicontrol(radioProps,...
                    'ButtonDownFcn','fm_axesdlg radio me', ...
                    'Enable','off', ...
                    'Position', [X+ColW/2 Y 3 uiH],...
                    'String', '',...
                    'Tag', [col 'DirNormal'],...
                    'ToolTip',[col 'Dir=''normal''']);
                set(rnormal,'UserData',rnormal2,'Tag','');
            end

            Y = Y-RowH*2/3;
            rreverse = uicontrol(radioProps,...
                'Position', [X+ColW/2 Y ColW/2 uiH],...
                'String', 'Reverse',...
                'Value', ~radioProps.Value,...
                'Tag', [col 'DirReverse'],...
                'ToolTip',[col 'Dir=''reverse''']);

            if MultDirs
                rreverse2 = uicontrol(radioProps,...
                    'ButtonDownFcn','fm_axesdlg radio me', ...
                    'Enable','off', ...
                    'Position', [X+ColW/2 Y 3 uiH],...
                    'String', '',...
                    'Tag', [col 'DirReverse'],...
                    'ToolTip',[col 'Dir=''reverse''']);
                set(rreverse,'UserData',rreverse2,'Tag','');
                set(rreverse2,'UserData',...
                    struct('Value',0,'Sibling',rreverse,'OtherRadio',rnormal2));
                set(rnormal2,'UserData',...
                    struct('Value',0,'Sibling',rnormal,'OtherRadio',rreverse2));
            end


            Y = Y-RowH*1/3;

            iGroup = iGroup+1;
            localData.LimGroup{iGroup} = [rnormal];
            localData.LimCheck(iGroup) = rreverse;
            localData.Enable{iGroup} = [];
            localData.Disable{iGroup} = [];

            iGroup = iGroup+1;
            localData.LimGroup{iGroup} = [rreverse];
            localData.LimCheck(iGroup) = rnormal;
            localData.Enable{iGroup} = [];
            localData.Disable{iGroup} = [];

            if MultDirs
                iGroup = iGroup+1;
                localData.LimGroup{iGroup} = [rnormal2];
                localData.LimCheck(iGroup) = rreverse2;
                localData.Enable{iGroup} = [];
                localData.Disable{iGroup} = [];

                iGroup = iGroup+1;
                localData.LimGroup{iGroup} = [rreverse2];
                localData.LimCheck(iGroup) = rnormal2;
                localData.Enable{iGroup} = [];
                localData.Disable{iGroup} = [];
            end

            % grid

            % Check if all axes grids are on
            AllGrids = strcmpi(get(ax,[col 'Grid']),'on');
            MultGrids = 0;
            if all(~AllGrids)
                checkProps.Value = 0;
            elseif all(AllGrids)
                checkProps.Value = 1;
            else
                MultGrids = 1;
                checkProps.Value = length(find(AllGrids))>=length(find(~AllGrids));
            end

            Y = Y-RowH;
            g = uicontrol(checkProps,...
                'String', 'On',...
                'Tag', [col 'Grid'],...
                'ToolTip', [col 'Grid'],...
                'Position', [X Y ColW/3 uiH],...
                'Callback', 'fm_axesdlg toggle me');

            iGroup = iGroup+1;
            localData.LimGroup{iGroup} = [];
            localData.LimCheck(iGroup) = g;
            localData.Enable{iGroup} = [];
            localData.Disable{iGroup} = [];

            if MultGrids
                g2 = uicontrol(checkProps,...
                    'ButtonDownFcn','fm_axesdlg toggle me', ...
                    'Enable','off', ...
                    'String', '',...
                    'Tag', [col 'Grid'],...
                    'ToolTip', [col 'Grid'],...
                    'UserData',struct('Value',checkProps.Value,'Sibling',g), ...
                    'Position', [X Y 3 uiH],...
                    'Callback', 'fm_axesdlg toggle me');
                set(g,'UserData',g2,'Tag','');
                iGroup = iGroup+1;
                localData.LimGroup{iGroup} = [];
                localData.LimCheck(iGroup) = g2;
                localData.Enable{iGroup} = [];
                localData.Disable{iGroup} = [];
            end

            iGroup = iGroup+1;

        end


        buttonX(1) = (figPos(3)-4*buttonW-3*buttonPad)/2;
        for ib = 2:4
            buttonX(ib) = buttonX(ib-1) + buttonW + buttonPad;
        end

        buttonProps = struct(...
            'Parent',f,...
            'Units','character',...
            'BackgroundColor', bgcolor,...
            'ForegroundColor', fgcolor,...
            'Position', [0 BotMarginH buttonW buttonH],...
            'Style', 'pushbutton');

        buttonProps.Position(1) = buttonX(1);
        u = uicontrol(buttonProps,...
            'Interruptible', 'off',...
            'String', 'OK',...
            'Callback', 'fm_axesdlg button ok');

        buttonProps.Position(1) = buttonX(2);
        uicontrol(buttonProps,...
            'Interruptible', 'off',...
            'String', 'Cancel',...
            'Callback', 'fm_axesdlg button cancel');

        buttonProps.Position(1) = buttonX(3);
        uicontrol(buttonProps,...
            'Interruptible', 'off',...
            'String', 'Help',...
            'Callback', 'fm_axesdlg showhelp me');

        buttonProps.Position(1) = buttonX(4);
        uicontrol(buttonProps,...
            'Interruptible', 'on',...
            'String', 'Apply',...
            'Callback', 'fm_axesdlg button apply');



        % finish opening axes dialog box
        set(fig,'Pointer',oldPointer);
        set(f,'Visible','on','Pointer','arrow');
        localData.axes = ax;


    catch
        set(fig,'Pointer',oldPointer);
        if exist('f')
            delete(f);
        end
        errordlg({'Couldn''t open axes properties dialog:' ...
                lasterr},...
            'Error',...
            'modal');
    end


    function [val,setflag] = getval(f,tag)
    uic = findobj(f,'Tag',tag);
    setflag = 1; % Flag for setting properties on multiple axes
    switch get(uic,'Style')
    case 'edit'
        val = get(uic, 'String');
        if isempty(val)
            setflag = 0;
        end
    case {'checkbox' 'radiobutton'}
        val = get(uic, 'Value');
        setflag = ~strcmp(get(uic,'Enable'),'off');
        if setflag && isstruct(get(uic,'UserData'));
            %---Making a previously non-common property, common
            LdeleteControl(uic)
        end
    end

    function val = setval(f,tag,val)
    uic = findobj(f,'Tag',tag);
    switch get(uic,'Style')
    case 'edit'
        set(uic, 'String',val);
    case {'checkbox' 'radiobutton'}
        set(uic, 'Value',val);
    end

    function localData = LApplySettings(f, localData)
    % get the values and set props:

    ax = localData.axes;

    iProp = 0;
    try
        % title
        val = getval(f,'Title');

        switch class(val)
        case 'char'
            if ~isempty(val) && size(val,1)>1
                % title returns as a string matrix
                % check for blank line at end of multiline title
                nTitleLines = size(val,1);
                if val(nTitleLines,:)==32  % true if all spaces
                    val(nTitleLines,:) = [];
                    setval(f,'Title',val);
                end
            end
        case 'cell'
            if length(val)>1
                nTitleLines = length(val);
                if isempty(val{nTitleLines}) || val{nTitleLines}==32
                    val(nTitleLines) = [];
                end
            end
        end

        CommonTitle = get(findobj(f,'Tag','Title'),'UserData');
        if ~(isempty(val) && length(ax)>1) || CommonTitle || length(ax)==1,
            t = get(ax,{'Title'});
            set([t{:}],'String',val);
            if ~CommonTitle, % They are common, now
                set(findobj(f,'Tag','Title'),'UserData',1)
            end
        end

        data = getappdata(f,'ScribeAxesDialogData');
        cols = 'XYZ';

        for i = 1:data.nCols
            col = cols(i);
            %label
            CommonLabel = get(findobj(f,'Tag',[col 'Label']),'UserData');
            val = getval(f,[col 'Label']);
            if ~(isempty(val) && length(ax)>1) || CommonLabel || length(ax)==1,
                t = get(ax,{[col 'Label']});
                set([t{:}],'String',val)
                if ~CommonLabel, % They are common, now
                    set(findobj(f,'Tag',[col 'Label']),'UserData',1)
                end
            end


            % scale
            [mode,setflag] = getval(f,[col 'ScaleLinear']);
            if setflag,
                iProp = iProp+1;
                axProps{iProp} = [col 'Scale'];
                modeswitch = {'log' 'linear'};
                axVals{iProp} = modeswitch{mode+1};
                % update immediately so that we get updated limits and ticks
                set(ax,axProps(iProp),axVals(iProp));
            end % if setflag

            linearScale = mode;

            %limitmode
            [manual,setflag] = getval(f,[col 'LimMode']);
            valMax=[]; valMin=[];
            limits=[];
            if setflag
                iProp = iProp+1;
                axProps{iProp} = [col 'LimMode'];
                modeswitch = {'auto' 'manual'};
                axVals{iProp} = modeswitch{manual+1};
                if manual
                    %limits
                    valMin = str2double(getval(f,[col 'LimMin']));
                    valMax = str2double(getval(f,[col 'LimMax']));
                    % ranges checked on callbacks
                    if ~(isnan(valMax) || isnan(valMin)),
                        iProp = iProp+1;
                        axProps{iProp} = [col 'Lim'];
                        limits = [valMin valMax];
                        axVals{iProp} = limits;
                    end
                else % auto
                    set(ax,[col 'LimMode'],'auto');
                    % Check for common limits
                    lim = get(ax,{[col 'Lim']});
                    lim = cat(1,lim{:});
                    Umin = unique(lim(:,1));
                    Umax = unique(lim(:,2));
                    if length(Umin)>1, uminStr = '';
                    else, uminStr = num2str(Umin);
                    end
                    if length(Umax)>1, umaxStr = '';
                    else, umaxStr = num2str(Umax);
                    end
                    setval(f, [col 'LimMin'], uminStr);
                    setval(f, [col 'LimMax'], umaxStr);
                end % if manual
            end % if setflag

            %tickmode
            TickInd=[];
            [manual,setflag] = getval(f,[col 'TickMode']);
            if setflag,
                iProp = iProp+1;
                axProps{iProp} = [col 'TickMode'];
                modeswitch = {'auto' 'manual'};
                axVals{iProp} = modeswitch{manual+1};

                if linearScale
                    if manual
                        tickstep = str2double(getval(f,[col 'TickStep']));
                        if ~isempty(tickstep), % Make sure something is there
                            if ~isempty(limits),
                                % Only preset ticks when everything is the same
                                iProp = iProp+1;
                                axProps{iProp} = [col 'Tick'];
                                ticks = limits(1):tickstep:limits(2);
                                % ranges checked on callbacks
                                axVals{iProp} = ticks;
                            else
                                TickInd = iProp;
                            end
                        end
                    else % auto
                        set(ax,[col 'TickMode'],'auto');
                        if length(ax)==1
                            ticks = get(ax,[col 'Tick']);
                            setval(f, [col 'TickStep'], ticks(2)-ticks(1));
                        end
                    end % if manual
                else % log scale
                    % manual mode disabled for log scale
                    set(ax,[col 'TickMode'],'auto');
                    setval(f, [col 'TickStep'], '');
                end
            end % if setflag

            % scale direction
            [mode,setflag] = getval(f,[col 'DirNormal']);
            if setflag,
                iProp = iProp+1;
                axProps{iProp} = [col 'Dir'];
                modeswitch = {'reverse' 'normal'};
                axVals{iProp} = modeswitch{mode+1};
            end

            % grid
            [mode,setflag] = getval(f,[col 'Grid']);
            if setflag,
                iProp = iProp+1;
                axProps{iProp} = [col 'Grid'];
                modeswitch = {'off' 'on'};
                axVals{iProp} = modeswitch{mode+1};
            end % if setflag

            if ~isempty(TickInd) || isnan(valMax) || isnan(valMin)
                % Going to have to loop thru to set limits/ticks individually
                for ct = 1:length(ax)
                    limits = get(ax(ct),[col 'Lim']);
                    axPropsCustom{1} = [col 'Lim'];
                    if ~isnan(valMax), limits(2) = valMax; end
                    if ~isnan(valMin), limits(1) = valMin; end
                    axValsCustom{1} = limits;

                    if ~isempty(TickInd);
                        axPropsCustom{2} = [col 'Tick'];
                        ticks = limits(1):tickstep:limits(2);
                        % ranges checked on callbacks
                        axValsCustom{2} = ticks;
                    end % if ~isempty(TickInd)

                    set(ax(ct),axPropsCustom,axValsCustom);
                end % for ct
            end

        end  % for col
        set(ax,axProps,axVals)
    catch
        % error somewhere in there...
    end % try/catch


    function LdeleteControl(OldControl)

    ud = get(OldControl,'UserData');
    set(ud.Sibling,'Value',get(OldControl,'Value'), ...
        'Tag',get(OldControl,'Tag'),'UserData',[])
    if isfield(ud,'OtherRadio'),
        ud2 = get(ud.OtherRadio,'UserData');
        set(ud2.Sibling,'Value',get(ud.OtherRadio,'Value'), ...
            'Tag',get(ud.OtherRadio,'Tag'),'UserData',[])
        delete(ud.OtherRadio)
    end
    delete(OldControl)


    function LNoAxesError
    errordlg(['No axes are selected.  Click on an axis to select it.']);
